#include "ast.hpp"
#include "logging.hpp"
#include <cstring>
#include <iostream>
#include <stack>
#define _AST_NODE_ERROR_                                   \
    std::cerr << "Abort due to node cast error."           \
                 "Contact with TAs to solve your problem." \
              << std::endl;                                \
    std::abort();
#define _STR_EQ(a, b) (strcmp((a), (b)) == 0)
void AST::run_visitor(ASTVisitor &visitor) { root->accept(visitor); }
AST::AST(parse_tree *s)
{
    if (s == nullptr)
    {
        std::cerr << "empty input tree!" << std::endl;
        std::abort();
    }
    auto node = transform_node_iter(s->root);
    del_parse_tree(s);
    root = std::shared_ptr<ASTProgram>(static_cast<ASTProgram *>(node));
}
ASTNode *AST::transform_node_iter(parse_tree_node *n)
{
    // 处理Program分析树节点
    if (_STR_EQ(n->name, "Program"))
    {
        auto node = new ASTProgram(); // 创建 ASTProgram 节点，表示整个程序
        // program -> CompUnit（解析程序的组成单元，例如变量声明、函数定义）
        std::stack<parse_tree_node *> s;
        auto list_ptr = n->children[0];
        while (list_ptr->children_num == 2) // 遍历所有的 CompUnit，并将它们依次压入栈中（CompUnit 可能是递归结构）
        {
            s.push(list_ptr->children[1]);
            list_ptr = list_ptr->children[0];
        }
        // 处理最后一个 CompUnit
        s.push(list_ptr->children[0]);
        while (!s.empty()) // 遍历栈中所有的 CompUnit，并转换成 AST 结构
        {
            auto child_node = static_cast<ASTCompUnit *>(transform_node_iter(s.top()));
            // 接受到上传回来的CompUnit整体
            auto child_node_shared = std::shared_ptr<ASTCompUnit>(child_node);
            // 这两个指向的是同一个东西，只是把类型调整了一下。
            node->compunits.push_back(child_node_shared);// 添加到 Program 节点中
            s.pop();
        }
        return node; 
    }
    else if (_STR_EQ(n->name, "Decl"))
    {
        auto node = new ASTDecl();
        // Decl 语法节点表示变量或常量的声明
        // 其子节点可能是 ConstDecl（常量声明）或 VarDecl（变量声明），由一个域is_const区分
        auto child = n->children[0]; // child is constDecl 或者 varDecl
        // 首先是常量声明
        // Decl -> ConstDecl
        // ConstDecl -> const BType ConstDefList ;
        // ConstDefList -> ConstDef | ConstDefList , ConstDef
        if (_STR_EQ(child->name, "ConstDecl"))
        {
            // 判断变量类型（BType 可能是 int 或 float）
            // ConstDecl -> const BType ConstDefList ;
            if (_STR_EQ(child->children[1]->children[0]->name, "int")) // 判断BType
                node->type = TYPE_INT;
            else
                node->type = TYPE_FLOAT;
            node->is_const = true; // 标记为常量声明
            std::stack<parse_tree_node *> s;
            auto list_ptr = child->children[2]; // ConstDefList，存放多个常量定义
            // 解析 ConstDefList（可能是递归结构）
            // ConstDefList 形态：ConstDef | ConstDefList ,dfs ConstDef
            while (list_ptr->children_num == 3) // 还有 `, ConstDef`，说明可以继续拆分
            {
                s.push(list_ptr->children[2]);     // 压入当前 `ConstDef`
                list_ptr = list_ptr->children[0]; // 继续深入 `ConstDefList`
            }
            s.push(list_ptr->children[0]); // 压入最后一个 `ConstDef`
            // 依次处理 `ConstDefList` 中的所有 `ConstDef`
            while (!s.empty())
            {
                auto child_node = static_cast<ASTDef *>(transform_node_iter(s.top())); // dfs的过程
                auto child_node_shared = std::shared_ptr<ASTDef>(child_node);
                node->def_lists.push_back(child_node_shared);
                s.pop();
            }
        }
        // 解析 `Decl -> VarDecl`（处理变量声明）
        // Decl -> VarDecl
        // VarDecl -> BType VarDef VarDeclList ;
        // VarDeclList -> VarDeclList , VarDef |
        else
        {
            // 判断变量类型（BType 可能是 int 或 float）
            if (_STR_EQ(child->children[0]->children[0]->name, "int"))
                node->type = TYPE_INT;
            else
                node->type = TYPE_FLOAT;
            node->is_const = false; // 标记为变量声明
            std::stack<parse_tree_node *> s;
            auto list_ptr = child->children[2]; // `VarDeclList`
            auto first = child->children[1];    // `VarDef`（第一个变量定义）
            // 解析 `VarDeclList`（递归结构）
            // `VarDeclList` 形态：VarDeclList ; VarDef
            while (list_ptr->children_num == 3) // 说明还有 `, VarDef`
            {
                s.push(list_ptr->children[2]); // 压入当前 `VarDef`
                list_ptr = list_ptr->children[0];  // 继续拆解 `VarDeclList`
            }
            s.push(first); // 将第一层的 `VarDef` 压入
            while (!s.empty())// 依次处理 `VarDeclList` 中的所有 `VarDef`
            { // dfs
                auto child_node = static_cast<ASTDef *>(transform_node_iter(s.top()));
                auto child_node_shared = std::shared_ptr<ASTDef>(child_node);
                node->def_lists.push_back(child_node_shared);
                s.pop();
            }
        }
        return node;
    }
    // ConstDef -> IDENT ConstExpList = ConstInitVal
    // ConstExpList -> ConstExpList [ ConstExp ]|epsilon
    else if (_STR_EQ(n->name, "ConstDef"))
    {
        // 这个地方还不涉及处理值的问题，这一层的任务主要是把ConstExpList拉平
        auto node = new ASTDef();
        // 获取标识符（变量名）
        node->id = n->children[0]->name;
        // 标记这个节点是常量
        node->is_const = true;
        // 处理数组的维度信息（ConstExpList）
        std::stack<parse_tree_node *> s_exp; // 用栈存储每个维度的大小,先出来的是最后一个维度的数组
        auto list_ptr = n->children[1];       // 这是list
        // 循环拆解 ConstExpList
        while (list_ptr->children_num == 4)  //表示含有`[ ConstExp ]` 可以继续拆前面的ConstExpList
        {
            s_exp.push(list_ptr->children[2]); // 把当前的维度信息（ConstExp）压入栈中
            list_ptr = list_ptr->children[0];  // 继续向下
        }
        // 将所有维度信息依次取出并存储
        while (!s_exp.empty())
        {
            auto exp_node = static_cast<ASTExp *>(transform_node_iter(s_exp.top()));
            auto exp_node_ptr = std::shared_ptr<ASTExp>(exp_node);
            node->exp_lists.push_back(exp_node_ptr);
            node->length++;
            s_exp.pop();
        }
       // 处理初始化值列表（ConstInitVal）
        // ConstInitVal -> ConstExp | {ConstInitValList} | {}
        // ConstInitValList -> ConstInitVal | ConstInitValList , ConstInitVal
        // 这里先不拆，只处理初始化的结构,先不拆的原因是不仅仅一层（含List）
        auto initval_node = static_cast<ASTInitVal *>(transform_node_iter(n->children[3]));
        auto initval_node_ptr = std::shared_ptr<ASTInitVal>(initval_node);
        node->initval_list = initval_node_ptr;
        return node;
    }
    // VarDef -> IDENT ConstExpList | IDENT ConstExpList = InitVal
    // ConstExpList -> ConstExpList [ ConstExp ] |
    else if (_STR_EQ(n->name, "VarDef"))
    {
        auto node = new ASTDef();
        // 获取变量的标识符（变量名）
        node->id = n->children[0]->name;
        // 标记该节点是变量（不是常量）
        node->is_const = false;
        // 处理数组维度（ConstExpList）
        std::stack<parse_tree_node *> s;
        auto list_ptr = n->children[1];
         // 遍历并处理每一个维度信息
        while (list_ptr->children_num == 4)
        {
            s.push(list_ptr->children[2]);
            list_ptr = list_ptr->children[0];
        }
         // 取出栈中的维度信息并存储
        while (!s.empty())
        {
            auto exp_node = static_cast<ASTExp *>(transform_node_iter(s.top()));
            auto exp_node_ptr = std::shared_ptr<ASTExp>(exp_node);
            node->exp_lists.push_back(exp_node_ptr);
            node->length++;
            s.pop();
        }
        if (n->children_num == 4) // 如果有初始值部分（即 '=' 后面的内容），处理初始化值
        {
            auto initval_node = static_cast<ASTInitVal *>(transform_node_iter(n->children[3]));
            auto initval_node_ptr = std::shared_ptr<ASTInitVal>(initval_node);
            node->initval_list = initval_node_ptr;
        }
        return node;
    }
    // ConstInitVal -> ConstExp | {ConstInitValList} | {}
    // ConstInitValList -> ConstInitVal | ConstInitValList , ConstInitVal
    else if (_STR_EQ(n->name, "ConstInitVal"))
    {
        auto node = new ASTInitVal();
        node->is_const = true;// 标记该节点为常量初始化值
        if (n->children_num == 1) // 只有一个子节点，表示只有一个常量值
        {
             // 获取常量表达式并保存
            auto exp_node = static_cast<ASTExp *>(transform_node_iter(n->children[0]));
            auto exp_node_ptr = std::shared_ptr<ASTExp>(exp_node);
            node->value = exp_node_ptr;// 将表达式存储到节点的value中
        }
        // 如果初始化值是一个列表（用大括号包围）
        // ConstInitVal -> { ConstInitValList }
        else if (n->children_num == 3) // 说明有多个初始化值
        {
            // 需要把大括号里的内容（ConstInitValList）展平成一个列表
            std::stack<parse_tree_node *> s;
            auto list_ptr = n->children[1];// 获取初始化值列表
            while (list_ptr->children_num == 3)// 继续拆解列表，直到把所有元素都提取出来
             // 处理"ConstInitValList -> ConstInitValList , ConstInitVal"
            {
                s.push(list_ptr->children[2]);
                list_ptr = list_ptr->children[0];
            }
            s.push(list_ptr->children[0]);
            // 依次取出栈中的初始化值，展平并存入节点的初始化值列表
            while (!s.empty())
            {
                auto initval_node = static_cast<ASTInitVal *>(transform_node_iter(s.top()));
                auto initval_node_ptr = std::shared_ptr<ASTInitVal>(initval_node);
                node->initval_list.push_back(initval_node_ptr);
                s.pop();
            }
        }
        // 如果初始化值为空（即 {}），处理空初始化的情况
        // ConstInitVal -> {}
        else
        {
            node->value = nullptr; // 值为空，孩子也是空，相当于上一层没有这个孩子
        }
        return node;
    }
    // InitVal -> Exp | { InitValList } | {}  （初始化值可以是一个表达式、一个列表或空）
    // InitValList -> InitVal | InitValList , InitVal  （初始化值列表可以是单个值或逗号分隔的多个值）
    else if (_STR_EQ(n->name, "InitVal"))
    {
        auto node = new ASTInitVal();
        node->is_const = false; // 这里与 `ConstInitVal` 不同，表示它是普通变量的初始化值
        // 情况 1：如果只有一个子节点，说明初始化值是一个单一的表达式
        if (n->children_num == 1)
        {
            // 直接转换表达式并存储
            auto exp_node = static_cast<ASTExp *>(transform_node_iter(n->children[0]));
            auto exp_node_ptr = std::shared_ptr<ASTExp>(exp_node);
            node->value = exp_node_ptr;
        }
        // 情况 2：如果有 `{ InitValList }`，说明是一个列表形式的初始化值，需要拆解
        else if (n->children_num == 3)
        {// 使用栈来展开 `InitValList`
            std::stack<parse_tree_node *> s;
            auto list_ptr = n->children[1];// 取出大括号内的 `InitValList`
            while (list_ptr->children_num == 3)// 处理形态为 `InitValList -> InitValList , InitVal` 的情况
            {
                s.push(list_ptr->children[2]); // 将当前的 `InitVal` 压入栈中
                list_ptr = list_ptr->children[0];// 继续拆解前面的 `InitValList`
            }
            s.push(list_ptr->children[0]);
            while (!s.empty())// 依次取出 `InitVal` 并存入 `initval_list`
            {
                auto initval_node = static_cast<ASTInitVal *>(transform_node_iter(s.top()));
                auto initval_node_ptr = std::shared_ptr<ASTInitVal>(initval_node);
                node->initval_list.push_back(initval_node_ptr);
                s.pop();
            }
        }
        // 情况 3：如果是 `{}`，表示初始化为空
        // InitVal -> {}
        else
        {
            node->value = nullptr;
        }
        return node;
    }
    // Exp -> AddExp
    else if (_STR_EQ(n->name, "Exp"))
    {
        auto node = new ASTExp();
        node->is_const = false;// 普通表达式，非常量
        // 解析 `AddExp`，即加法表达式（可能包含加、减运算）
        auto addexp_node = static_cast<ASTAddExp *>(transform_node_iter(n->children[0]));
        auto addexp_node_ptr = std::shared_ptr<ASTAddExp>(addexp_node);
        node->add_exp = addexp_node_ptr;// 存储 `AddExp` 作为 `Exp` 的子节点
        return node;
    }
    // ConstExp -> AddExp
    else if (_STR_EQ(n->name, "ConstExp"))
    {
        auto node = new ASTExp();
        node->is_const = true;// 该表达式为常量
        // 解析 `AddExp`，同上
        auto addexp_node = static_cast<ASTAddExp *>(transform_node_iter(n->children[0]));
        auto addexp_node_ptr = std::shared_ptr<ASTAddExp>(addexp_node);
        node->add_exp = addexp_node_ptr;// 存储 `AddExp` 作为 `ConstExp` 的子节点
        return node;
    }
    // 函数定义
    // FuncDef -> BType|void IDENT ( FuncFParams ) Block
    // FuncDef -> BType|void IDENT () Block
    // FuncFParams -> FuncFParam | FuncFParams , FuncFParam
    // 这里直接解析参数列表（FuncFParams），但不拆函数体（Block）
    else if (_STR_EQ(n->name, "FuncDef"))
    {
        auto node = new ASTFuncDef();
        // 解析函数名
        node->id = n->children[1]->name;
        // 解析返回类型
        if (_STR_EQ(n->children[0]->name, "void"))
        {
            node->type = TYPE_VOID;
        }
        else
        {
            if (_STR_EQ(n->children[0]->children[0]->name, "int"))
                node->type = TYPE_INT;
            else
                node->type = TYPE_FLOAT; // 假设只处理 int 和 float
        }
        // 解析参数列表
        // FuncDef -> BType|void IDENT ( FuncFParams ) Block
        // FuncFParams -> FuncFParams , FuncFParam | FuncParam
        // FuncFParam -> BType IDENT [] ExpList
        // ExpList -> ExpList [ Exp ] |
        if (n->children_num == 6) // 说明存在参数列表 ( FuncFParams )
        {
            std::stack<parse_tree_node *> s;
            auto list_ptr = n->children[3]; // FuncFParams 位置
            // 解析参数列表，将参数依次存入栈中，保持原顺序
            while (list_ptr->children_num == 3) // FuncFParams -> FuncFParams , FuncFParam
            {
                s.push(list_ptr->children[2]);
                list_ptr = list_ptr->children[0];
            }
            s.push(list_ptr->children[0]);
            while (!s.empty())// 依次弹出栈中的参数，按原顺序存入参数列表
            {
                auto child_node = static_cast<ASTParam *>(transform_node_iter(s.top()));
                auto child_node_shared = std::shared_ptr<ASTParam>(child_node);
                node->params.push_back(child_node_shared);
                s.pop();
            }
            // 解析函数体
            auto block_node = static_cast<ASTBlock *>(transform_node_iter(n->children[5]));
            node->block = std::shared_ptr<ASTBlock>(block_node);
        }
        // FuncDef -> BType|void IDENT () Block （无参数）
        else
        {// 直接解析函数体
            auto block_node = static_cast<ASTBlock *>(transform_node_iter(n->children[4]));
            node->block = std::shared_ptr<ASTBlock>(block_node);
        }
        return node;
    }
    // 解析函数参数
    // FuncFParam -> BType IDENT [] ExpList    
    // FuncFParam -> BType IDENT   
    // ExpList -> ExpList [ Exp ] |    
    else if (_STR_EQ(n->name, "FuncFParam"))
    {
        auto node = new ASTParam();
        // 解析参数类型 (int 或 float)
        if (_STR_EQ(n->children[0]->children[0]->name, "int"))
            node->type = TYPE_INT;
        else
            node->type = TYPE_FLOAT;
        // 解析参数名
        node->id = n->children[1]->name;
        // 是否是一个数组类型的参数
        // FuncFParam -> BType IDENT
        if (n->children_num == 2)// 只有 "BType IDENT"，说明是普通变量
            node->isarray = false;
        else// 带有方括号 "[]"，说明是数组
        {
            node->isarray = true;
            // 解析数组的维度信息
            // 结构示例: ExpList -> ExpList [ Exp ] -> ExpList [ Exp ] -> ...
            std::stack<parse_tree_node *> s;
            auto list_ptr = n->children[4];// 访问 ExpList 节点
            // 逐层遍历 ExpList，将每个维度的 Exp 压入栈中
            while (list_ptr->children_num == 4)// 说明 ExpList 仍然包含下一层，继续拆
            {
                s.push(list_ptr->children[2]);// 存入当前维度的 Exp
                list_ptr = list_ptr->children[0];// 继续向左遍历
            }
            // 按照正确的顺序 (从外层到内层) 存入 array_lists
            while (!s.empty())
            {
                auto child_node = static_cast<ASTExp *>(transform_node_iter(s.top()));
                auto child_node_ptr = std::shared_ptr<ASTExp>(child_node);
                node->array_lists.push_back(child_node_ptr);
                s.pop();
            }
        }
        return node;
    }
    // Block -> { BlcokList }
    // Block -> | BlockList BlockItem
    // BlockItem -> Decl | Stmt
    else if (_STR_EQ(n->name, "Block"))
    {
        auto node = new ASTBlock();
        std::stack<parse_tree_node *> s;
        auto list_ptr = n->children[1];
        // 遍历 BlockList，将 BlockItem 存入栈中 (逆序存入, 方便后续按顺序处理)
        while (list_ptr->children_num == 2)
        {
            s.push(list_ptr->children[1]);// 存入 BlockItem
            list_ptr = list_ptr->children[0];// 继续遍历 BlockList
        }
        while (!s.empty()) // 处理 BlockItem (Decl | Stmt)
        {
            if (_STR_EQ(s.top()->children[0]->name, "Decl"))// 处理变量声明
            {
                auto child_node = static_cast<ASTDecl *>(transform_node_iter(s.top()->children[0]));
                auto child_node_ptr = std::shared_ptr<ASTDecl>(child_node);
                node->decl_lists.push_back(child_node_ptr);
                node->list_type.push_back(0);// 0 表示 Decl
                s.pop();
            }
            else // 处理语句 Stmt
            {
                // auto child_node = static_cast<ASTStmt *>(transform_node_iter(s.top()->children[0]));
                ASTStmt *child_node;
                // Stmt -> ;
                if (_STR_EQ(s.top()->children[0]->children[0]->name, ";"))//空语句
                    child_node = nullptr;
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "LVal"))// Stmt -> LVal = Exp ;
                {
                    // 赋值语句
                    auto node = new ASTAssignStmt();
                    auto var_node = static_cast<ASTVar *>(transform_node_iter(s.top()->children[0]->children[0]));
                    node->var = std::shared_ptr<ASTVar>(var_node);
                    auto exp_node = static_cast<ASTExp *>(transform_node_iter(s.top()->children[0]->children[2]));
                    node->expression = std::shared_ptr<ASTExp>(exp_node);
                    child_node = static_cast<ASTStmt *>(node);
                }
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "Exp"))// Stmt ->Exp ;
                {
                    // 
                    child_node = static_cast<ASTStmt *>(transform_node_iter(s.top()->children[0]->children[0]));
                    // return transform_node_iter(n->children[0]);
                }
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "Block"))// Stmt ->Block
                {
                    // 
                    child_node = static_cast<ASTStmt *>(transform_node_iter(s.top()->children[0]->children[0]));
                    // return transform_node_iter(n->children[0]);
                }
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "if")) //if语句
                {
                    // 
                    auto node = new ASTSelectionStmt();
                    auto cond_node = static_cast<ASTLOrExp *>(transform_node_iter(s.top()->children[0]->children[2]->children[0]));
                    node->cond = std::shared_ptr<ASTLOrExp>(cond_node);
                    auto if_stmt_node = static_cast<ASTStmt *>(transform_node_iter(s.top()->children[0]->children[4]));
                    node->if_stmt = std::shared_ptr<ASTStmt>(if_stmt_node);
                    if (s.top()->children[0]->children_num == 7)// 存在 else 分支
                    {
                        auto else_stmt_node = static_cast<ASTStmt *>(transform_node_iter(s.top()->children[0]->children[6]));
                        node->else_stmt = std::shared_ptr<ASTStmt>(else_stmt_node);
                    }
                    child_node = static_cast<ASTStmt *>(node);
                }
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "while"))// while 循环
                {
                    // 
                    auto node = new ASTIterationStmt();
                    auto cond_node = static_cast<ASTLOrExp *>(transform_node_iter(s.top()->children[0]->children[2]->children[0]));
                    node->cond = std::shared_ptr<ASTLOrExp>(cond_node);
                    auto stmt_node = static_cast<ASTStmt *>(transform_node_iter(s.top()->children[0]->children[4]));
                    node->stmt = std::shared_ptr<ASTStmt>(stmt_node);
                    child_node = static_cast<ASTStmt *>(node);
                    // return node;
                }
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "break"))// break 语句
                {
                    // 
                    auto node = new ASTBreak();
                    node->is_break = true;
                    // return node;
                    child_node = static_cast<ASTStmt *>(node);
                }
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "continue"))// continue 语句
                {
                    // 
                    auto node = new ASTContinue();
                    node->is_continue = true;
                    // return node;
                    child_node = static_cast<ASTStmt *>(node);
                }
                else if (_STR_EQ(s.top()->children[0]->children[0]->name, "return"))// return 语句
                {
                    // 
                    auto node = new ASTReturnStmt();
                    if (s.top()->children[0]->children_num == 3)// 存在返回值
                    {
                        auto exp_node = static_cast<ASTExp *>(transform_node_iter(s.top()->children[0]->children[1]));
                        node->expression = std::shared_ptr<ASTExp>(exp_node);
                    }
                    // return node;
                    child_node = static_cast<ASTStmt *>(node);
                }
                // error
                else
                {
                    std::cerr << "[ast]: transform failure!" << std::endl;
                    std::cerr << "when transform stmt, encoutner unknown expression" << std::endl;
                    std::abort();
                }
                if (child_node != nullptr)// 记录有效的语句
                {
                    auto child_node_ptr = std::shared_ptr<ASTStmt>(child_node);
                    node->stmt_lists.push_back(child_node_ptr);
                    node->list_type.push_back(1);
                }
                s.pop();
            }
        }
        return node;
    }
    // Stmt 的产生式合集
    // 1. 赋值语句 (AssignStmt) -> LVal = Exp ;
    // 2. 表达式语句 (Exp) -> Exp ;
    // 3. 代码块 (Block) -> { Stmt* }
    // 4. 选择语句 (selectionStmt) -> if (Exp) Stmt [else Stmt]
    // 5. 循环语句 (iterationStmt) -> while (Exp) Stmt
    // 6. 控制流语句 -> break; | continue; | return [Exp];
    // 与Block中逻辑一致
    else if (_STR_EQ(n->name, "Stmt"))
    {
        // Stmt -> LVal = Exp ;
        if (_STR_EQ(n->children[0]->name, ";"))
            return nullptr;
        if (_STR_EQ(n->children[0]->name, "LVal"))
        {
            auto node = new ASTAssignStmt();
            auto var_node = static_cast<ASTVar *>(transform_node_iter(n->children[0]));
            node->var = std::shared_ptr<ASTVar>(var_node);
            auto exp_node = static_cast<ASTExp *>(transform_node_iter(n->children[2]));
            node->expression = std::shared_ptr<ASTExp>(exp_node);
            return node;
        }
        else if (_STR_EQ(n->children[0]->name, "Exp"))
        {
            return transform_node_iter(n->children[0]);
        }
        else if (_STR_EQ(n->children[0]->name, "Block"))
        {
            return transform_node_iter(n->children[0]);
        }
        else if (_STR_EQ(n->children[0]->name, "if"))
        {
            auto node = new ASTSelectionStmt();
            auto cond_node = static_cast<ASTLOrExp *>(transform_node_iter(n->children[2]->children[0]));
            node->cond = std::shared_ptr<ASTLOrExp>(cond_node);
            auto if_stmt_node = static_cast<ASTStmt *>(transform_node_iter(n->children[4]));
            node->if_stmt = std::shared_ptr<ASTStmt>(if_stmt_node);
            if (n->children_num == 7)
            {
                auto else_stmt_node = static_cast<ASTStmt *>(transform_node_iter(n->children[6]));
                node->else_stmt = std::shared_ptr<ASTStmt>(else_stmt_node);
            }
            return node;
        }
        else if (_STR_EQ(n->children[0]->name, "while"))
        {
            auto node = new ASTIterationStmt();
            auto cond_node = static_cast<ASTLOrExp *>(transform_node_iter(n->children[2]->children[0]));
            node->cond = std::shared_ptr<ASTLOrExp>(cond_node);
            auto stmt_node = static_cast<ASTStmt *>(transform_node_iter(n->children[4]));
            node->stmt = std::shared_ptr<ASTStmt>(stmt_node);
            return node;
        }
        else if (_STR_EQ(n->children[0]->name, "break"))
        {
            auto node = new ASTBreak();
            node->is_break = true;
            return node;
        }
        else if (_STR_EQ(n->children[0]->name, "continue"))
        {
            auto node = new ASTContinue();
            node->is_continue = true;
            return node;
        }
        else if (_STR_EQ(n->children[0]->name, "return"))
        {
            auto node = new ASTReturnStmt();
            if (n->children_num == 3)
            {
                auto exp_node = static_cast<ASTExp *>(transform_node_iter(n->children[1]));
                node->expression = std::shared_ptr<ASTExp>(exp_node);
            }
            return node;
        }
        // error
        else
        {
            std::cerr << "[ast]: transform failure!" << std::endl;
            std::cerr << "when transform stmt, encoutner unknown expression" << std::endl;
            std::abort();
        }
    }
    // LVal -> IDENT ExpList
    // ExpList -> ExpList [Exp] |
    else if (_STR_EQ(n->name, "LVal"))
    {
        auto node = new ASTVar();
        node->id = n->children[0]->name;
        std::stack<parse_tree_node *> s;
        auto list_ptr = n->children[1];
        // 解析数组下标访问，例如：arr[0][1][2]
       // 这里使用栈来倒序存储下标表达式，因为语法树是从右向左递归构造的
        while (list_ptr->children_num == 4)// 形如 ExpList [Exp]
        {
            s.push(list_ptr->children[2]);
            list_ptr = list_ptr->children[0];
        }
        // 依次从栈中弹出表达式，按正确的顺序加入数组访问列表
        while (!s.empty())
        {
            auto child_node = static_cast<ASTExp *>(transform_node_iter(s.top()));
            auto child_node_ptr = std::shared_ptr<ASTExp>(child_node);
            node->length++;
            node->array_lists.push_back(child_node_ptr);// 存储数组下标表达式
            s.pop();
        }
        return node;
    }
    // LOrExp -> LAndExp | LOrExp OR LAndExp
    else if (_STR_EQ(n->name, "LOrExp"))
    {
        auto node = new ASTLOrExp();
        // 处理形如 `a || b` 的表达式
        if (n->children_num == 3)// LOrExp || LAndExp
        {
            auto lor_exp_node = static_cast<ASTLOrExp *>(transform_node_iter(n->children[0]));// 左操作数
            node->lor_exp = std::shared_ptr<ASTLOrExp>(lor_exp_node);
            node->or_op = OP_OR;// 逻辑或操作符
            auto and_exp_node = static_cast<ASTLAndExp *>(transform_node_iter(n->children[2]));// 右操作数
            node->land_exp = std::shared_ptr<ASTLAndExp>(and_exp_node);
        }
        // 处理单独的逻辑与表达式，例如 `a && b`
        else// 仅有一个 LAndExp
        {
            auto and_exp_node = static_cast<ASTLAndExp *>(transform_node_iter(n->children[0]));
            node->land_exp = std::shared_ptr<ASTLAndExp>(and_exp_node);
        }
        return node;
    }
    // LAndExp -> EqExp | LAndExp AND EqExp
    else if (_STR_EQ(n->name, "LAndExp"))
    {
        auto node = new ASTLAndExp();
        if (n->children_num == 3)// LAndExp && EqExp
        {
            auto land_exp_node = static_cast<ASTLAndExp *>(transform_node_iter(n->children[0]));
            node->land_exp = std::shared_ptr<ASTLAndExp>(land_exp_node);
            node->and_op = OP_AND;
            auto eq_exp_node = static_cast<ASTEqExp *>(transform_node_iter(n->children[2]));
            node->eq_exp = std::shared_ptr<ASTEqExp>(eq_exp_node);
        }
        else// 仅有一个 EqExp
        {
            auto eq_exp_node = static_cast<ASTEqExp *>(transform_node_iter(n->children[0]));
            node->eq_exp = std::shared_ptr<ASTEqExp>(eq_exp_node);
        }
        return node;
    }
    else if (_STR_EQ(n->name, "EqExp"))
    {
        auto node = new ASTEqExp();
        if (n->children_num == 3)// EqExp ==/!= RelExp
        {
            auto eq_exp_node = static_cast<ASTEqExp *>(transform_node_iter(n->children[0]));
            node->eq_exp = std::shared_ptr<ASTEqExp>(eq_exp_node);
            if (_STR_EQ(n->children[1]->name, "=="))
            {
                node->op = OP_EQ;
            }
            else
            {
                node->op = OP_NEQ;
            }
            auto rel_exp_node = static_cast<ASTRelExp *>(transform_node_iter(n->children[2]));
            node->rel_exp = std::shared_ptr<ASTRelExp>(rel_exp_node);
        }
        else// 仅有一个 RelExp
        {
            auto rel_exp_node = static_cast<ASTRelExp *>(transform_node_iter(n->children[0]));
            node->rel_exp = std::shared_ptr<ASTRelExp>(rel_exp_node);
        }
        return node;
    }
    else if (_STR_EQ(n->name, "RelExp"))
    {
        auto node = new ASTRelExp();
        // 处理形如 `a < b`、`a <= b`、`a > b` 或 `a >= b` 的表达式
        if (n->children_num == 3)
        {
            auto rel_exp_node = static_cast<ASTRelExp *>(transform_node_iter(n->children[0]));
            node->rel_exp = std::shared_ptr<ASTRelExp>(rel_exp_node);
            if (_STR_EQ(n->children[1]->name, "<"))
            {
                node->op = OP_LT;
            }
            else if (_STR_EQ(n->children[1]->name, "<="))
            {
                node->op = OP_LE;
            }
            else if (_STR_EQ(n->children[1]->name, ">"))
            {
                node->op = OP_GT;
            }
            else
            {
                node->op = OP_GE;
            }
            auto add_exp_node = static_cast<ASTAddExp *>(transform_node_iter(n->children[2]));// 递归解析右侧的AddExp部分
            node->add_exp = std::shared_ptr<ASTAddExp>(add_exp_node);
        }
        else// 只有一个 AddExp
        {
            auto add_exp_node = static_cast<ASTAddExp *>(transform_node_iter(n->children[0]));
            node->add_exp = std::shared_ptr<ASTAddExp>(add_exp_node);
        }
        return node;
    }
    // 解析加法表达式 (AddExp)
    // 加法表达式处理的是加法 (`+`) 和减法 (`-`) 操作
    // 产生式规则：
    // AddExp -> AddExp + MulExp     // 加法
    // AddExp -> AddExp - MulExp     // 减法
    // AddExp -> MulExp              // 单一乘法表达式
    else if (_STR_EQ(n->name, "AddExp"))
    {
        auto node = new ASTAddExp();
        auto outer = node;  // 保存原始节点，以便返回
        while (1)
        {
            if (n->children_num == 3)// 如果当前节点有三个子节点，表示是加法或减法
            {
                if (_STR_EQ(n->children[1]->name, "+"))
                {
                    node->op = OP_ADD;
                }
                else
                {
                    node->op = OP_SUB;
                }
                auto mul_exp_node = static_cast<ASTMulExp *>(transform_node_iter(n->children[2]));// 递归解析右侧的MulExp
                node->mul_exp = std::shared_ptr<ASTMulExp>(mul_exp_node);
                // 创建新的AddExp节点，为链式AddExp做准备
                auto new_node = new ASTAddExp();
                node->add_exp = std::shared_ptr<ASTAddExp>(new_node);
                node = new_node;
                n = n->children[0];
            }
            else// 如果当前节点只有一个MulExp
            {
                auto mul_exp_node = static_cast<ASTMulExp *>(transform_node_iter(n->children[0]));
                node->mul_exp = std::shared_ptr<ASTMulExp>(mul_exp_node);
                node->add_exp = nullptr;
                break;
            }
        }
        return outer;// 返回最外层的AddExp节点
    }
    // 解析乘法表达式 (MulExp)
    // 乘法表达式处理的是乘法 (`*`)、除法 (`/`) 和取模 (`%`) 操作
    // 产生式规则：
    // MulExp -> MulExp * UnaryExp     // 乘法
    // MulExp -> MulExp / UnaryExp     // 除法
    // MulExp -> MulExp % UnaryExp     // 取模
    // MulExp -> UnaryExp              // 单一一元表达式
    else if (_STR_EQ(n->name, "MulExp"))
    {
        auto node = new ASTMulExp();
        if (n->children_num == 3)// 如果当前节点有三个子节点，表示是乘法、除法或取模
        {
            // 递归解析左侧的MulExp部分
            auto mul_exp_node = static_cast<ASTMulExp *>(transform_node_iter(n->children[0]));
            node->mul_exp = std::shared_ptr<ASTMulExp>(mul_exp_node);
            if (_STR_EQ(n->children[1]->name, "*"))// 根据操作符设置乘法、除法或取模操作
            {
                node->op = OP_MUL;
            }
            else if (_STR_EQ(n->children[1]->name, "/"))
            {
                node->op = OP_DIV;
            }
            else
            {
                node->op = OP_MOD;
            }
            // 递归解析右侧的一元表达式部分
            auto unary_exp_node = static_cast<ASTUnaryExp *>(transform_node_iter(n->children[2]));
            node->unary_exp = std::shared_ptr<ASTUnaryExp>(unary_exp_node);
        }
        else// 如果当前节点只有一个一元表达式
        {
            // 递归解析一元表达式
            auto unary_exp_node = static_cast<ASTUnaryExp *>(transform_node_iter(n->children[0]));
            node->unary_exp = std::shared_ptr<ASTUnaryExp>(unary_exp_node);
        }
        return node;
    }
    else if (_STR_EQ(n->name, "UnaryExp"))
    {
        // UnaryExp -> PrimaryExp
        auto node = new ASTUnaryExp();
        if (n->children_num == 1)
        {
            auto primary_node = static_cast<ASTPrimaryExp *>(transform_node_iter(n->children[0]));
            node->primary_exp = std::shared_ptr<ASTPrimaryExp>(primary_node);
        }
        else if (n->children_num == 2)// UnaryExp -> UnaryOp UnaryExp
        {
            if (_STR_EQ(n->children[0]->children[0]->name, "+"))
                node->unary_op = OP_PLUS;
            else if (_STR_EQ(n->children[0]->children[0]->name, "-"))
                node->unary_op = OP_MINUS;
            else
                node->unary_op = OP_NOT;
            auto unary_exp_node = static_cast<ASTUnaryExp *>(transform_node_iter(n->children[1]));
            node->unary_exp = std::shared_ptr<ASTUnaryExp>(unary_exp_node);
        }
        else // 如果有3个及以上子节点，表示是函数调用
        {
            auto call_node = new ASTCall();
            call_node->id = n->children[0]->name;
            if (n->children_num == 4)// 如果有参数列表，递归解析参数
            {
                std::stack<parse_tree_node *> s;
                auto list_ptr = n->children[2];//FuncRParams
                while (list_ptr->children_num == 3)// 处理参数列表FuncRParams
                {//FuncRParams-> FuncRParams , Exp
                    s.push(list_ptr->children[2]);//Exp
                    list_ptr = list_ptr->children[0];
                }
                s.push(list_ptr->children[0]);
                while (!s.empty())// 将解析出的参数添加到函数调用节点
                {
                    auto child_node = static_cast<ASTExp *>(transform_node_iter(s.top()));
                    auto child_node_ptr = std::shared_ptr<ASTExp>(child_node);
                    call_node->args.push_back(child_node_ptr);
                    s.pop();
                }
            }
            node->call_exp = std::shared_ptr<ASTCall>(call_node);// 将函数调用节点关联到一元表达式
        }
        return node;
    }
    else if (_STR_EQ(n->name, "PrimaryExp"))
    {
        if (n->children_num == 1)//PrimaryExp -> LVal | Number
            return transform_node_iter(n->children[0]);
        else//PrimaryExp -> LPARENTHESIS Exp RPARENTHESIS 
        {
            return transform_node_iter(n->children[1]);
        }
    }
    else if (_STR_EQ(n->name, "Number"))
    {
        auto node = new ASTNum();
        if (_STR_EQ(n->children[0]->name, "Integer"))
        {
            node->type = TYPE_INT; // 设置类型为整数
            std::string value = n->children[0]->children[0]->name;
            if (value[1] == 'x' || value[1] == 'X')// 判断是否为十六进制
                node->i_val = std::stoi(value, nullptr, 16); // 十六进制转换
            else if (value[0] == '0' && value.length() > 1)// 判断是否为八进制
                node->i_val = std::stoi(value, nullptr, 8); // 八进制转换
            else
                node->i_val = std::stoi(n->children[0]->children[0]->name);// 普通的十进制整数转换
        }
        else if (_STR_EQ(n->children[0]->name, "Floatnum"))// 处理浮点数类型
        {
            std::string value = n->children[0]->children[0]->name;
            node->type = TYPE_FLOAT;// 设置类型为浮点数
            if (value[1] == 'x' || value[1] == 'X') // 判断是否为十六进制浮点数
            {
                char *endPtr;
                node->f_val = (float)std::strtod(value.c_str(), &endPtr); // 手动转换为浮点数
            }
            else
            {
                node->f_val = std::stof(value, nullptr);
            }
        }
        else
        {
            std::cerr << n->children[0]->name << std::endl;
            std::cerr << "Wrong Type" << std::endl;
            std::abort();
        }
        return node;
    }
    else
    {
        std::cerr << n->name << std::endl;
        std::cerr << "[ast]: transform failure!" << std::endl;
        std::abort();
    }
}
Value *ASTProgram::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTFuncDef::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTDecl::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTDef::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTParam::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTBlock::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTAssignStmt::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTSelectionStmt::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTIterationStmt::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTBreak::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTContinue::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTReturnStmt::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTVar::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTNum::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTUnaryExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTCall::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTAddExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTMulExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTRelExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTEqExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTLAndExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTLOrExp::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
Value *ASTInitVal::accept(ASTVisitor &visitor) { return visitor.visit(*this); }
// 打印一棵AST
#define _DEBUT_PRINT_N_(N)                \
    {                                     \
        std::cout << std::string(N, '-'); \
    }
Value *ASTPrinter::visit(ASTProgram &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "Program" << std::endl;
    add_depth();
    for (auto comp : node.compunits)
    {
        comp->accept(*this);
    }
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTNum &node)
{
    _DEBUT_PRINT_N_(depth);
    if (node.type == TYPE_INT)
    {
        std::cout << "num(int): " << node.i_val << std::endl;
    }
    else if (node.type == TYPE_FLOAT)
    {
        std::cout << "num(float): " << node.f_val << std::endl;
    }
    else
    {
        _AST_NODE_ERROR_
    }
   return nullptr;
}
Value *ASTPrinter::visit(ASTDecl &node)
{
    _DEBUT_PRINT_N_(depth);
    if (node.is_const)
    {
        std::cout << "ConstDecl: " << std::endl;
    }
    else
    {
        std::cout << "Decl: " << std::endl;
    }
    for (auto def : node.def_lists)
    {
        add_depth();
        def->accept(*this);
        remove_depth();
    }
   return nullptr;
}
Value *ASTPrinter::visit(ASTFuncDef &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "FuncDef: " << node.id << std::endl;
    add_depth();
    for (auto param : node.params)
    {
        param->accept(*this);
    }
    node.block->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTDef &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << node.id << std::endl;
    std::cout << node.type << std::endl;
    if (node.length > 0)
    {
        for (auto exp : node.exp_lists)
        {
            add_depth();
            _DEBUT_PRINT_N_(depth);
            std::cout << "[]" << std::endl;
            exp->accept(*this);
            remove_depth();
        }
    }
    if (node.initval_list != nullptr)
    {
        add_depth();
        _DEBUT_PRINT_N_(depth);
        std::cout << "=" << std::endl;
        node.initval_list->accept(*this);
        remove_depth();
    }
   return nullptr;
}
Value *ASTPrinter::visit(ASTParam &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "param: " << std::endl;
    if (node.type == TYPE_INT)
    {
        std::cout << "int " << node.id;
    }
    else
    {
        std::cout << "float " << node.id;
    }
    if (node.isarray)
        std::cout << "[]" << std::endl;
    else
        std::cout << std::endl;
    if (!node.array_lists.empty())
    {
        for (auto array : node.array_lists)
        {
            add_depth();
            _DEBUT_PRINT_N_(depth);
            std::cout << "[]" << std::endl;
            array->accept(*this);
            remove_depth();
        }
    }
   return nullptr;
}
Value *ASTPrinter::visit(ASTBlock &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "Block" << std::endl;
    add_depth();
    for (auto decl : node.decl_lists)
    {
        decl->accept(*this);
    }
    for (auto stmt : node.stmt_lists)
    {
        stmt->accept(*this);
    }
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTAssignStmt &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "AssignStmt: " << std::endl;
    add_depth();
    node.var->accept(*this);
    node.expression->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTSelectionStmt &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "SelectionStmt: " << std::endl;
    add_depth();
    node.cond->accept(*this);
    if (node.if_stmt != nullptr)
        node.if_stmt->accept(*this);
    if (node.else_stmt != nullptr)
        node.else_stmt->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTIterationStmt &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "IterationStmt: " << std::endl;
    add_depth();
    node.cond->accept(*this);
    if (node.stmt != nullptr)
        node.stmt->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTReturnStmt &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "ReturnStmt: " << std::endl;
    if (node.expression == nullptr)
    {
        std::cout << ": void" << std::endl;
    }
    else
    {
        add_depth();
        node.expression->accept(*this);
        remove_depth();
    }
   return nullptr;
}
Value *ASTPrinter::visit(ASTBreak &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "Break" << std::endl;
   return nullptr;
}
Value *ASTPrinter::visit(ASTContinue &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "Continue" << std::endl;
   return nullptr;
}
Value *ASTPrinter::visit(ASTExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "expression" << std::endl;
    add_depth();
    if (node.add_exp != nullptr)
        node.add_exp->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTVar &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "var: " << node.id << std::endl;
    if (node.length > 0)
    {
        for (auto array : node.array_lists)
        {
            add_depth();
            _DEBUT_PRINT_N_(depth);
            std::cout << "[]" << std::endl;
            array->accept(*this);
            remove_depth();
        }
    }
   return nullptr;
}
Value *ASTPrinter::visit(ASTUnaryExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "UnaryExp: " << std::endl;
    if (node.unary_exp != nullptr)
    {
        _DEBUT_PRINT_N_(depth);
        if (node.unary_op == OP_PLUS)
            std::cout << "+";
        else if (node.unary_op == OP_MINUS)
            std::cout << "-";
        else
            std::cout << "!";
        add_depth();
        node.unary_exp->accept(*this);
        remove_depth();
    }
    else if (node.primary_exp != nullptr)
    {
        add_depth();
        node.primary_exp->accept(*this);
        remove_depth();
    }
    else if (node.call_exp != nullptr)
    {
        add_depth();
        node.call_exp->accept(*this);
        remove_depth();
    }
    else
    {
        _AST_NODE_ERROR_
    }
   return nullptr;
}
Value *ASTPrinter::visit(ASTCall &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "Call :" << node.id << "()" << std::endl;
    add_depth();
    for (auto arg : node.args)
    {
        arg->accept(*this);
    }
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTAddExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "AddExp: ";
    if (node.add_exp == nullptr)
        std::cout << std::endl;
    else
    {
        std::cout << ": ";
        if (node.op == OP_ADD)
            std::cout << "+";
        else if (node.op == OP_SUB)
            std::cout << "-";
        else
            std::abort();
        std::cout << std::endl;
    }
    add_depth();
    if (node.add_exp != nullptr)
        node.add_exp->accept(*this);
    node.mul_exp->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTMulExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "MulExp: ";
    if (node.mul_exp == nullptr)
        std::cout << std::endl;
    else
    {
        std::cout << ": ";
        if (node.op == OP_MUL)
            std::cout << "*";
        else if (node.op == OP_DIV)
            std::cout << "/";
        else if (node.op == OP_MOD)
            std::cout << "%";
        else
            std::abort();
        std::cout << std::endl;
    }
    add_depth();
    if (node.mul_exp != nullptr)
        node.mul_exp->accept(*this);
    node.unary_exp->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTRelExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "RelExp: ";
    if (node.rel_exp == nullptr)
        std::cout << std::endl;
    else
    {
        std::cout << ": ";
        if (node.op == OP_LT)
            std::cout << "<";
        else if (node.op == OP_LE)
            std::cout << "<=";
        else if (node.op == OP_GT)
            std::cout << ">";
        else if (node.op == OP_GE)
            std::cout << ">=";
        else
            std::abort();
        std::cout << std::endl;
    }
    add_depth();
    if (node.rel_exp != nullptr)
        node.rel_exp->accept(*this);
    node.add_exp->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTEqExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "EqExp: ";
    if (node.eq_exp == nullptr)
        std::cout << std::endl;
    else
    {
        std::cout << ": ";
        if (node.op == OP_EQ)
            std::cout << "==";
        else if (node.op == OP_NEQ)
            std::cout << "!=";
        else
            std::abort();
        std::cout << std::endl;
    }
    add_depth();
    if (node.eq_exp != nullptr)
        node.eq_exp->accept(*this);
    node.rel_exp->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTLAndExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "LAndExp: ";
    if (node.land_exp == nullptr)
        std::cout << std::endl;
    else
    {
        std::cout << ": ";
        if (node.and_op == OP_AND)
            std::cout << "&&";
        else
            std::abort();
        std::cout << std::endl;
    }
    add_depth();
    if (node.land_exp != nullptr)
        node.land_exp->accept(*this);
    node.eq_exp->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTLOrExp &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "LOrExp: ";
    if (node.lor_exp == nullptr)
        std::cout << std::endl;
    else
    {
        std::cout << ": ";
        if (node.or_op == OP_OR)
            std::cout << "||";
        else
            std::abort();
        std::cout << std::endl;
    }
    add_depth();
    if (node.lor_exp != nullptr)
        node.lor_exp->accept(*this);
    node.land_exp->accept(*this);
    remove_depth();
   return nullptr;
}
Value *ASTPrinter::visit(ASTInitVal &node)
{
    _DEBUT_PRINT_N_(depth);
    std::cout << "InitVal: " << std::endl;
    if (!node.initval_list.empty())
    {
        add_depth();
        _DEBUT_PRINT_N_(depth);
        std::cout << "{" << std::endl;
        for (auto initval : node.initval_list)
        {
            add_depth();
            initval->accept(*this);
            remove_depth();
        }
        _DEBUT_PRINT_N_(depth);
        std::cout << "}" << std::endl;
        remove_depth();
    }
    else
    {
        add_depth();
        if (node.value != nullptr)
            node.value->accept(*this);
        else
        {
            _DEBUT_PRINT_N_(depth);
            std::cout << "{}" << std::endl;
        }
        remove_depth();
    }
   return nullptr;
}
